import type { Context } from 'elysia';
import { mkdir, writeFile, unlink, stat } from 'fs/promises';
import { existsSync } from 'fs';
import path from 'path';
import sharp from 'sharp';

const UPLOAD_DIR = path.join(process.cwd(), 'public', 'uploads');
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
const MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5MB for images
const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
const ALLOWED_FILE_TYPES = [...ALLOWED_IMAGE_TYPES, 'application/pdf', 'text/plain'];
const DANGEROUS_EXTENSIONS = ['.exe', '.bat', '.cmd', '.com', '.pif', '.scr', '.vbs', '.js', '.jar', '.php', '.asp', '.jsp'];

/**
 * 确保上传目录存在
 */
export async function ensureUploadDir() {
  if (!existsSync(UPLOAD_DIR)) {
    await mkdir(UPLOAD_DIR, { recursive: true });
  }
  
  // 创建子目录
  const subDirs = ['images', 'documents', 'temp'];
  for (const subDir of subDirs) {
    const dirPath = path.join(UPLOAD_DIR, subDir);
    if (!existsSync(dirPath)) {
      await mkdir(dirPath, { recursive: true });
    }
  }
}

/**
 * 生成唯一文件名
 */
export function generateFileName(originalName: string): string {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 8);
  const ext = path.extname(originalName);
  const baseName = path.basename(originalName, ext).replace(/[^a-zA-Z0-9]/g, '_');
  return `${timestamp}_${random}_${baseName}${ext}`;
}

/**
 * 验证文件类型和大小
 */
export function validateFile(file: File, allowedTypes: string[] = ALLOWED_FILE_TYPES): { valid: boolean; error?: string } {
  // 检查文件大小
  const maxSize = ALLOWED_IMAGE_TYPES.includes(file.type) ? MAX_IMAGE_SIZE : MAX_FILE_SIZE;
  if (file.size > maxSize) {
    return {
      valid: false,
      error: `文件大小不能超过 ${maxSize / 1024 / 1024}MB`
    };
  }
  
  // 检查文件类型
  if (!allowedTypes.includes(file.type)) {
    return {
      valid: false,
      error: `不支持的文件类型: ${file.type}`
    };
  }
  
  // 检查文件扩展名安全性
  const ext = path.extname(file.name).toLowerCase();
  if (DANGEROUS_EXTENSIONS.includes(ext)) {
    return {
      valid: false,
      error: `危险的文件扩展名: ${ext}`
    };
  }
  
  // 检查文件名长度
  if (file.name.length > 255) {
    return {
      valid: false,
      error: '文件名过长'
    };
  }
  
  return { valid: true };
}

/**
 * 处理图片上传和压缩
 */
export async function processImageUpload(file: File, options: {
  maxWidth?: number;
  maxHeight?: number;
  quality?: number;
  format?: 'jpeg' | 'png' | 'webp';
} = {}): Promise<{ success: boolean; filePath?: string; url?: string; error?: string }> {
  try {
    await ensureUploadDir();
    
    const validation = validateFile(file, ALLOWED_IMAGE_TYPES);
    if (!validation.valid) {
      return { success: false, error: validation.error };
    }
    
    const fileName = generateFileName(file.name);
    const filePath = path.join(UPLOAD_DIR, 'images', fileName);
    
    // 读取文件内容
    const arrayBuffer = await file.arrayBuffer();
    const buffer = Buffer.from(arrayBuffer);
    
    // 使用 Sharp 处理图片
    let sharpInstance = sharp(buffer);
    
    // 调整大小
    if (options.maxWidth || options.maxHeight) {
      sharpInstance = sharpInstance.resize({
        width: options.maxWidth,
        height: options.maxHeight,
        fit: 'inside',
        withoutEnlargement: true
      });
    }
    
    // 设置格式和质量
    if (options.format === 'jpeg') {
      sharpInstance = sharpInstance.jpeg({ quality: options.quality || 85 });
    } else if (options.format === 'png') {
      sharpInstance = sharpInstance.png({ quality: options.quality || 85 });
    } else if (options.format === 'webp') {
      sharpInstance = sharpInstance.webp({ quality: options.quality || 85 });
    }
    
    // 保存处理后的图片
    await sharpInstance.toFile(filePath);
    
    const url = `/uploads/images/${fileName}`;
    
    return {
      success: true,
      filePath,
      url
    };
  } catch (error) {
    console.error('Image upload error:', error);
    return {
      success: false,
      error: '图片上传失败'
    };
  }
}

/**
 * 处理普通文件上传
 */
export async function processFileUpload(file: File): Promise<{ success: boolean; filePath?: string; url?: string; error?: string }> {
  try {
    await ensureUploadDir();
    
    const validation = validateFile(file);
    if (!validation.valid) {
      return { success: false, error: validation.error };
    }
    
    const fileName = generateFileName(file.name);
    const filePath = path.join(UPLOAD_DIR, 'documents', fileName);
    
    // 读取文件内容并保存
    const arrayBuffer = await file.arrayBuffer();
    const buffer = Buffer.from(arrayBuffer);
    await writeFile(filePath, buffer);
    
    const url = `/uploads/documents/${fileName}`;
    
    return {
      success: true,
      filePath,
      url
    };
  } catch (error) {
    console.error('File upload error:', error);
    return {
      success: false,
      error: '文件上传失败'
    };
  }
}

/**
 * 删除文件
 */
export async function deleteFile(filePath: string): Promise<{ success: boolean; error?: string }> {
  try {
    // 安全检查：确保文件在上传目录内
    const normalizedPath = path.normalize(filePath);
    const uploadDirNormalized = path.normalize(UPLOAD_DIR);
    
    if (!normalizedPath.startsWith(uploadDirNormalized)) {
      return {
        success: false,
        error: '无效的文件路径'
      };
    }
    
    // 检查文件是否存在
    if (!existsSync(normalizedPath)) {
      return {
        success: false,
        error: '文件不存在'
      };
    }
    
    // 删除文件
    await unlink(normalizedPath);
    
    // console.log(`File deleted: ${normalizedPath}`);
    return { success: true };
  } catch (error) {
    console.error('Delete file error:', error);
    return {
      success: false,
      error: '删除文件失败'
    };
  }
}

/**
 * 获取文件信息
 */
export async function getFileInfo(filePath: string): Promise<{ success: boolean; info?: any; error?: string }> {
  try {
    // 安全检查：确保文件在上传目录内
    const normalizedPath = path.normalize(filePath);
    const uploadDirNormalized = path.normalize(UPLOAD_DIR);
    
    if (!normalizedPath.startsWith(uploadDirNormalized)) {
      return {
        success: false,
        error: '无效的文件路径'
      };
    }
    
    // 检查文件是否存在
    if (!existsSync(normalizedPath)) {
      return {
        success: false,
        error: '文件不存在'
      };
    }
    
    const stats = await stat(normalizedPath);
    const fileName = path.basename(normalizedPath);
    const ext = path.extname(normalizedPath);
    
    return {
      success: true,
      info: {
        name: fileName,
        size: stats.size,
        extension: ext,
        created: stats.birthtime,
        modified: stats.mtime,
        isDirectory: stats.isDirectory(),
        isFile: stats.isFile()
      }
    };
  } catch (error) {
    console.error('Get file info error:', error);
    return {
      success: false,
      error: '获取文件信息失败'
    };
  }
}

/**
 * 清理临时文件（删除超过24小时的临时文件）
 */
export async function cleanupTempFiles(): Promise<void> {
  try {
    const tempDir = path.join(UPLOAD_DIR, 'temp');
    if (!existsSync(tempDir)) return;
    
    const fs = await import('fs/promises');
    const files = await fs.readdir(tempDir);
    const now = Date.now();
    const oneDayMs = 24 * 60 * 60 * 1000;
    
    for (const file of files) {
      const filePath = path.join(tempDir, file);
      const stats = await stat(filePath);
      
      if (now - stats.mtime.getTime() > oneDayMs) {
        await unlink(filePath);
        // console.log(`Cleaned up temp file: ${filePath}`);
      }
    }
  } catch (error) {
    console.error('Cleanup temp files error:', error);
  }
}

/**
 * 上传中间件
 */
export function uploadMiddleware() {
  return async ({ body, set }: Context) => {
    try {
      if (!body || typeof body !== 'object') {
        set.status = 400;
        return {
          success: false,
          message: '请提供文件',
          code: 'NO_FILE'
        };
      }
      
      return { uploadBody: body };
    } catch (error) {
      console.error('Upload middleware error:', error);
      set.status = 500;
      return {
        success: false,
        message: '文件处理失败',
        code: 'UPLOAD_ERROR'
      };
    }
  };
}